package top.wshape1.easyscan.ui;

import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.graphics.Rect;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.Toast;

import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;

import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.huawei.hms.hmsscankit.OnLightVisibleCallBack;
import com.huawei.hms.hmsscankit.OnResultCallback;
import com.huawei.hms.hmsscankit.RemoteView;
import com.huawei.hms.ml.scan.HmsScan;

import java.lang.reflect.Method;

import top.wshape1.easyscan.activity.EasyScanActivity;
import top.wshape1.easyscan.constraint.PackageEnum;
import top.wshape1.easyscan.custom.ApplicationJumpDialog;
import top.wshape1.easyscan.databinding.FragmentScanBinding;
import top.wshape1.easyscan.entity.CustomRule;
import top.wshape1.easyscan.util.GoToUtil;
import top.wshape1.easyscan.util.CodeStringUtil;

public class ScanFragment extends Fragment {

    public static final String TAG = "ScanFragment";

    private final int SCAN_FRAME_SIZE = 250;
    // view
    private ImageButton flashSwitch;

    private FrameLayout frameLayout;

    private RemoteView remoteView;

    private FragmentScanBinding binding;

    private EasyScanActivity mainActivity;

    private ApplicationJumpDialog jumpDialog;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mainActivity = (EasyScanActivity) this.getActivity();
        remoteView = createRemoteView();
        remoteView.onCreate(savedInstanceState);

    }

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {

        binding = FragmentScanBinding.inflate(inflater, container, false);
        View root = binding.getRoot();

        flashSwitch = binding.flashSwitch;
        frameLayout = binding.scannerArea;


        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        frameLayout.addView(remoteView, params);
        frameLayout.bringChildToFront(binding.scannerFrame);
        frameLayout.bringChildToFront(flashSwitch);

        // 事件设置
        // 闪关灯开关
        flashSwitch.setOnClickListener(flashSwitchClickListener);
        // 闪关灯光暗检测 按钮隐藏
        remoteView.setOnLightVisibleCallback(lightVisibleCallBack);

        jumpDialog = mainActivity.jumpDialog;

        return root;
    }

    /**
     * 设置跳转提示信息
     * @param packageEnum
     */
    private void setJumpDialogInfo(PackageEnum packageEnum) {
        ApplicationInfo applicationInfo = mainActivity.getGoalAppInfoBy(packageEnum.getPackageName());
        jumpDialog.setJumpIcon(applicationInfo.loadIcon(mainActivity.getPackageManager()));
        jumpDialog.setJumpTitle(applicationInfo.loadLabel(mainActivity.getPackageManager()));
    }

    /**
     * 方法重载setJumpDialogInfo(PackageEnum packageEnum)
     * @param packageName
     */
    private void setJumpDialogInfo(String packageName) {
        ApplicationInfo applicationInfo = mainActivity.getGoalAppInfoBy(packageName);
        jumpDialog.setJumpIcon(applicationInfo.loadIcon(mainActivity.getPackageManager()));
        jumpDialog.setJumpTitle(applicationInfo.loadLabel(mainActivity.getPackageManager()));
    }

    private RemoteView createRemoteView() {
        // 1.获取屏幕分辨率来计算扫描框的尺寸。
        DisplayMetrics dm = getResources().getDisplayMetrics();
        float density = dm.density;

        // 2.获取屏幕尺寸。
        int mScreenWidth = getResources().getDisplayMetrics().widthPixels;
        int mScreenHeight = getResources().getDisplayMetrics().heightPixels;
        int scanFrameSize = (int) (SCAN_FRAME_SIZE * density);

        // 3.计算扫描框位置，当前扫描框在屏幕中间。
        // 设置扫描框位置(可选配置，如果不设置默认在屏幕中间)。
        Rect rect = new Rect();
        rect.left = mScreenWidth / 2 - scanFrameSize / 2;
        rect.right = mScreenWidth / 2 + scanFrameSize / 2;
        rect.top = mScreenHeight / 2 - scanFrameSize / 2;
        rect.bottom = mScreenHeight / 2 + scanFrameSize / 2;

        // 初始化RemoteView并设置回调函数接收扫码结果。
        RemoteView remoteView = new RemoteView.Builder()
                .setContext(mainActivity)
                .setBoundingBox(rect)
                .setFormat(HmsScan.ALL_SCAN_TYPE)
                .build();
        remoteView.setOnResultCallback(scanResultCallback);
        return remoteView;
    }

    /**
     * 闪关灯切换
     */
    private void toggleFlashSwitchImg() {
        if (remoteView.getLightStatus()) {
            flashSwitch.setImageResource(com.huawei.hms.scankit.R.drawable.scankit_flashlight_layer_off);
        } else {
            flashSwitch.setImageResource(com.huawei.hms.scankit.R.drawable.scankit_flashlight_layer_on);
        }
    }

    /**
     * 显示底部弹窗
     * @param originalValue
     */
    private void showBottomSheetDialog(String originalValue) {
        BottomSheetDialog bottomSheetDialog = mainActivity.getBottomSheetDialog(originalValue);
        bottomSheetDialog.setOnDismissListener(dismissListener);
        bottomSheetDialog.show();
    }

    //manage remoteView lifecycle
    @Override
    public void onStart() {
        super.onStart();
        remoteView.onStart();
    }

    @Override
    public void onResume() {
        super.onResume();
        remoteView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        if (remoteView.getLightStatus())
            toggleFlashSwitchImg();
        remoteView.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        remoteView.onDestroy();
    }

    @Override
    public void onStop() {
        super.onStop();
        remoteView.onStop();
    }

    private final View.OnClickListener flashSwitchClickListener = v -> {
        toggleFlashSwitchImg();
        if (!remoteView.switchLight()) {
            Toast.makeText(mainActivity, "使用闪关灯失败!", Toast.LENGTH_SHORT).show();
        }
    };

    private final DialogInterface.OnDismissListener dismissListener = dialog -> remoteView.onStart();

    /**
     * 二维码回调方法
     */
    private final OnResultCallback scanResultCallback = result -> {
        if (result != null && result.length > 0 && result[0] != null && !TextUtils.isEmpty(result[0].getOriginalValue())) {
            String originalValue = result[0].getOriginalValue();

//            Toast.makeText(mainActivity, originalValue, Toast.LENGTH_SHORT).show();
            // 停止扫描
            remoteView.onStop();
            // 解析结果
            PackageEnum packageEnum = CodeStringUtil.resolveQrString(originalValue);

            // 匹配到
            if (packageEnum != null) {

                Class<GoToUtil> clazz = GoToUtil.class;
                Method method;
                try {
                    if (packageEnum == PackageEnum.URL) {

                        if (mainActivity.settingData.isUrlJump()) {
                            setJumpDialogInfo(PackageEnum.EASYSCAN);
                            jumpDialog.setJumpTitle("链接跳转");
                            jumpDialog.setJumpText("正在跳转中...");
                            jumpDialog.show();
                            method = clazz.getDeclaredMethod(GoToUtil.getMethodName(packageEnum), EasyScanActivity.class, String.class);
                            method.invoke(GoToUtil.class, mainActivity, originalValue);
                        } else {

                            excCustomRuleOrDialog(originalValue);
                        }
                    } else {
                        // 跳转提示框
                        setJumpDialogInfo(packageEnum);
                        jumpDialog.show();
                        method = clazz.getDeclaredMethod(GoToUtil.getMethodName(packageEnum), EasyScanActivity.class);
                        method.invoke(GoToUtil.class, mainActivity);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
//                    Toast.makeText(mainActivity, "发生错误", Toast.LENGTH_SHORT).show();
                    showBottomSheetDialog(originalValue);
                }

            } else {

                // 匹配自定义规则
                excCustomRuleOrDialog(originalValue);

            }
        }
    };

    /**
     * 匹配自定义规则或直接展示原始数据
     *
     * @param originalValue
     */
    private void excCustomRuleOrDialog(String originalValue) {
        boolean customFind = false;
        for (CustomRule customRule : mainActivity.settingData.getCustomRuleList()) {

            if ((customRule.getType() == 0 && originalValue.contains(customRule.getMatchString())) ||
                    (customRule.getType() == 1 && originalValue.startsWith(customRule.getMatchString())) ||
                    (customRule.getType() == 2 && originalValue.endsWith(customRule.getMatchString())) ||
                    (customRule.getType() == 3 && originalValue.matches(customRule.getMatchString()))
            ) {
                customFind = true;
            }

            if (customFind) {

                setJumpDialogInfo(customRule.getPackageName());
                jumpDialog.show();

                Intent intent = mainActivity.getPackageManager().getLaunchIntentForPackage(customRule.getPackageName());
                mainActivity.startActivity(intent);
                break;
            }
        }

        // 直接展示原始数据
        if (!customFind)
            showBottomSheetDialog(originalValue);
    }


    private final OnLightVisibleCallBack lightVisibleCallBack = b -> {
        Log.i(TAG, "onLightVisibleCallBack: " + b);
//        true：场景昏暗。
//        false：场景明亮。
        if (remoteView.getLightStatus())
            toggleFlashSwitchImg();
        if (b) {
            flashSwitch.setVisibility(View.VISIBLE);
        } else {
            flashSwitch.setVisibility(View.INVISIBLE);

        }
    };


}